/**
 *
 */
package com.elcom.emocbc.cbm.smsbroadcast;

import com.elcom.emocbc.cbm.BroadcastDTO;
import static com.elcom.emocbc.cbm.CellBroadcastService.SIZE_TO_COPY;
import com.elcom.emocbc.cbm.MenuItemDTO;
import java.util.List;

import com.elcom.emocbc.db.CellBroadcastDAO;
import com.elcom.emocbc.util.ConfigurationManager;
import com.elcom.emocbc.util.GeneratorSeq;
import com.elcom.emocbc.util.Hex;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author tiamo114
 *
 */
public class SmsBroadcastJob implements Runnable {

    private final static Logger logger = LoggerFactory.getLogger(SmsBroadcastJob.class);
    private BroadcastDTO broadcast = null;
    private CellBroadcastDAO dao = null;
    private static final String ACTION_CODE = "30";
    private final String[] msisdnList;

    public SmsBroadcastJob(BroadcastDTO broadcast, String[] msisdnList) {
        dao = new CellBroadcastDAO();
        this.broadcast = broadcast;
        this.msisdnList = msisdnList;
    }

    @Override
    public void run() {

        List<MenuItemDTO> listMenu = dao.getListMenuItem(broadcast.getTopicID(), broadcast.getProgramID());
        String display = dao.getDisplayContent(broadcast.getProgramID());
        logger.debug("Zone {} - Time {} - Broadcasting subcontent: {}", broadcast.getZone(), broadcast.getStartTime(), display);

        // Create an array containing the elements in a list
        MenuItemDTO[] menu = new MenuItemDTO[listMenu.size()];
        for (int i = 0; i < menu.length; i++) {
            menu[i] = listMenu.get(i);
        }

        try {
            int messageID = GeneratorSeq.getNextSeq();
            byte[] sum = generateCBMStructFile(menu, display, messageID, broadcast);

            SmsBroadcaster smsBroadcaster = new SmsBroadcaster(sum, messageID, msisdnList);
            new Thread(smsBroadcaster).start();

            logger.info("Zone {} - Time {} - Finish broadcast for: {}", broadcast.getZone(), broadcast.getStartTime(), broadcast.toString());
        } catch (Exception e) {
            logger.error("", e);
        }

    }

    private static String getMostContent(String addresses[]) {
        int howMany;
        int mostTimes = 1;
        String mostCommon = null;
        for (String addresse : addresses) {
            if (addresse == null || addresse.length() == 0) {
                continue;
            }
            howMany = 0;
            for (String addresse1 : addresses) {
                if (addresse.equals(addresse1)) {
                    howMany++;
                }
            }
            if (howMany > mostTimes) {
                mostTimes = howMany;
                mostCommon = addresse;
            }
        }

        return mostCommon;
    }

    private static int getMostNumber(int addresses[]) {
        int howMany;
        int mostTimes = 1;
        int mostCommon = 0;
        for (int i = 0; i < addresses.length; i++) {
            if (addresses[i] == 0) {
                continue;
            }
            howMany = 0;
            for (int j = 0; j < addresses.length; j++) {
                if (addresses[i] == (addresses[j])) {
                    howMany++;
                }
            }

            if (howMany > mostTimes) {
                mostTimes = howMany;
                mostCommon = addresses[i];
            }
        }

        return mostCommon;
    }

    public static byte[] generateCBMStructFile(MenuItemDTO[] menu, String detail, int messageID, BroadcastDTO broadcastDTO)
            throws IOException {
        int detailSize = detail.length();
        String beginHex = "";
        String menuHex = "";
        String detailHex = "";
        String separators = ConfigurationManager.getStrProp("cell_broadcast", "separators", "");

        ByteBuffer b = ByteBuffer.allocate(4);
        b.putInt(messageID);
        byte[] array = Arrays.copyOfRange(b.array(), 3, 4);//chi lay byte cuoi
        String messageIdHex1Byte = Hex.convertBinary2Hexadecimal(array);

        int[] number = new int[menu.length];
        for (int i = 0; i < number.length; i++) {
            number[i] = menu[i].getShortcode();
        }
        int defaultNumber = getMostNumber(number);

        String[] content = new String[menu.length];
        for (int i = 0; i < content.length; i++) {
            content[i] = menu[i].getContent();
            logger.debug("content{}: {}", i, content[i]);
        }
        String defaultContent = getMostContent(content);

        //for Test
//		defaultNumber = 0;
//		defaultContent = null;
        int topicID = 0;//fix for mobifone
        logger.debug("[MsgId: {}]Start broadcast for topicID: {}---defaultNumber={}---defaultContent={}", messageIdHex1Byte, topicID, defaultNumber, defaultContent);

        if (defaultNumber == 0 && defaultContent == null) {//OK DONE
            //<editor-fold defaultstate="collapsed" desc="No shortcode, no content">
            for (int i = 0; i < menu.length; i++) {
                if (menu[i].getType().startsWith("ZZ")) {
                    menuHex += menu[i].getType();
                    menuHex += Hex.integerToHex(menu[i].getContent().length());
                } else {
                    menuHex += menu[i].getType() + "81";
                    menuHex += toShortCodeString(menu[i].getShortcode());

                    String tmp = Hex.integerToHex(menu[i].getContent().length());
                    if (menu[i].getType().equals("B3")) {
                        tmp = tmp.replaceFirst("0", "8");
                    }

                    menuHex += tmp;
                }

                menuHex += Hex.stringToHex(menu[i].getContent());
                menuHex += Hex.integerToHex(menu[i].getDisplay().length()) + Hex.stringToHex(menu[i].getDisplay());
            }

            // Init
            int numberMenu = menu.length;
            beginHex = ACTION_CODE
                    + "0" + numberMenu + Hex.integerToHex(topicID)
                    + "0000" + separators;
            int beginLength = (beginHex.length() + menuHex.length()) / 2;
            beginHex = Hex.integerToHex(beginLength) + beginHex;

            detailHex = "010200" + Hex.integerToHex(detailSize + 2) + Hex.stringToHex(detail);
            //</editor-fold>
        } else if (defaultNumber != 0 && defaultContent == null) {//OK DONE
            //<editor-fold defaultstate="collapsed" desc="Have shortcode, No content">
            for (int i = 0; i < menu.length; i++) {
                if (menu[i].getType().equals("A3")) {
                    if (menu[i].getShortcode() == defaultNumber) {
                        menu[i].setType("A0");
                        menuHex += menu[i].getType();
                    } else {
                        menuHex += menu[i].getType() + "81";
                        menuHex += toShortCodeString(menu[i].getShortcode());
                    }
                    menuHex += Hex.integerToHex(menu[i].getContent().length());

                } else {
                    if (menu[i].getShortcode() == defaultNumber) {
                        menu[i].setType("B0");
                        menuHex += menu[i].getType();
                    } else {
                        menuHex += menu[i].getType() + "81";
                        menuHex += toShortCodeString(menu[i].getShortcode());
                    }

                    String tmp = Hex.integerToHex(menu[i].getContent().length());
                    if (menu[i].getType().equals("B3")) {
                        tmp = tmp.replaceFirst("0", "8");
                    }
                    menuHex += tmp;
                }

                menuHex += Hex.stringToHex(menu[i].getContent());
                menuHex += Hex.integerToHex(menu[i].getDisplay().length()) + Hex.stringToHex(menu[i].getDisplay());
            }

            // Init
            int numberMenu = menu.length;
            beginHex = ACTION_CODE
                    + "0" + numberMenu + Hex.integerToHex(topicID)
                    + "0381" + toShortCodeString(defaultNumber) + "00" + separators;
            int beginLength = (beginHex.length() + menuHex.length()) / 2;
            beginHex = Hex.integerToHex(beginLength) + beginHex;

            detailHex = "010200" + Hex.integerToHex(detailSize + 2) + Hex.stringToHex(detail);

            //</editor-fold>
        } else if (defaultNumber == 0 && defaultContent != null) {
            //<editor-fold defaultstate="collapsed" desc="No shortcode, have content">
            for (int i = 0; i < menu.length; i++) {
                menuHex += menu[i].getType() + "81";
                menuHex += toShortCodeString(menu[i].getShortcode());

                if (menu[i].getContent().equals(defaultContent)) {
                    if (menu[i].getType().startsWith("A")) {
                        menuHex += "00";
                    } else {
                        menuHex += "80";
                    }
                } else {
                    if (menu[i].getType().startsWith("A")) {
                        menuHex += Hex.integerToHex(menu[i].getContent().length());
                    } else {
                        String tmp = Hex.integerToHex(menu[i].getContent().length());
                        if (menu[i].getType().equals("B3")) {
                            tmp = tmp.replaceFirst("0", "8");
                        }
                        menuHex += tmp;
                    }

                    menuHex += Hex.stringToHex(menu[i].getContent());
                }

                menuHex += Hex.integerToHex(menu[i].getDisplay().length()) + Hex.stringToHex(menu[i].getDisplay());
                //
                //
                //				menuHex += Hex.stringToHex(menu[i].getContent());
                //				menuHex += Hex.IntegerToHex(menu[i].getDisplay().length()) + Hex.stringToHex(menu[i].getDisplay());
                //
                //				menuSize += menu[i].getContent().length() + 1;
                //				menuSize += menu[i].getDisplay().length() + 1;
            }
            //ThanhTT- Them 23-10-2012
            defaultContent = Hex.stringToHex(defaultContent);
            //End- ThanhTT

            // Init
            int numberMenu = menu.length;
            beginHex = ACTION_CODE
                    + "0" + numberMenu + Hex.integerToHex(topicID)
                    + "00" + Hex.integerToHex(defaultContent.length() / 2) + defaultContent + separators;
            int beginLength = (beginHex.length() + menuHex.length()) / 2;
            beginHex = Hex.integerToHex(beginLength) + beginHex;

            detailHex = "010200" + Hex.integerToHex(detailSize + 2) + Hex.stringToHex(detail);

            //</editor-fold>
        } else if (defaultNumber != 0 && defaultContent != null) {
            //<editor-fold defaultstate="collapsed" desc="Have shortcode, have content">
            for (int i = 0; i < menu.length; i++) {
                if (menu[i].getType().equals("A3")) {
                    if (menu[i].getShortcode() == defaultNumber) {
                        menu[i].setType("A0");
                        menuHex += menu[i].getType();
                    } else {
                        menuHex += menu[i].getType() + "81";
                        menuHex += toShortCodeString(menu[i].getShortcode());
                    }
                } else {
                    if (menu[i].getShortcode() == defaultNumber) {
                        menu[i].setType("B0");
                        menuHex += menu[i].getType();
                    } else {
                        menuHex += menu[i].getType() + "81";
                        menuHex += toShortCodeString(menu[i].getShortcode());
                    }
                }

                if (menu[i].getContent().equals(defaultContent)) {
                    if (menu[i].getType().startsWith("A")) {
                        menuHex += "00";
                    } else {
                        menuHex += "80";
                    }
                } else {
                    if (menu[i].getType().startsWith("A")) {
                        menuHex += Hex.integerToHex(menu[i].getContent().length());
                    } else {
                        String tmp = Hex.integerToHex(menu[i].getContent().length());
                        if (menu[i].getType().equals("B3")) {
                            tmp = tmp.replaceFirst("0", "8");
                        }
                        menuHex += tmp;
                    }

                    menuHex += Hex.stringToHex(menu[i].getContent());
                }

                menuHex += Hex.integerToHex(menu[i].getDisplay().length()) + Hex.stringToHex(menu[i].getDisplay());
            }
            //ThanhTT- Them 23-10-2012
            defaultContent = Hex.stringToHex(defaultContent);
            //End- ThanhTT

            // Init
            int numberMenu = menu.length;
            beginHex = ACTION_CODE
                    + "0" + numberMenu + Hex.integerToHex(topicID)
                    + "0381" + toShortCodeString(defaultNumber) + Hex.integerToHex(defaultContent.length() / 2) + defaultContent + separators;
            int beginLength = (beginHex.length() + menuHex.length()) / 2;
            beginHex = Hex.integerToHex(beginLength) + beginHex;

            detailHex = "010200" + Hex.integerToHex(detailSize + 2) + Hex.stringToHex(detail);

            //</editor-fold>
        }

        int currentSize = (beginHex.length() + menuHex.length() + detailHex.length()) / 2;
        logger.debug("[MsgId: {}]Current size: {}", messageIdHex1Byte, currentSize);
        int remaining = SIZE_TO_COPY - (currentSize % SIZE_TO_COPY);
        logger.debug("[MsgId: {}]remaining size: {}", messageIdHex1Byte, remaining);
        for (int i = 0; i < remaining; i++) {
            detailHex += "0D";
        }
        logger.debug("[MsgId: {}]Test broadcast: {}---{}---{}", messageIdHex1Byte, beginHex, menuHex, detailHex);

        byte[] beginArray = Hex.hexStringToByteArray(beginHex);
        byte[] menuArray = Hex.hexStringToByteArray(menuHex);
        byte[] detailArray = Hex.hexStringToByteArray(detailHex);

        byte[] sum = new byte[beginArray.length + menuArray.length + detailArray.length];
        System.arraycopy(beginArray, 0, sum, 0, beginArray.length);
        System.arraycopy(menuArray, 0, sum, beginArray.length, menuArray.length);
        System.arraycopy(detailArray, 0, sum, beginArray.length + menuArray.length, detailArray.length);

        return sum;
    }

    private static String toShortCodeString(int defaultCode) {
        StringBuilder shortCode = new StringBuilder(String.valueOf(defaultCode));
        if (shortCode.length() % 2 == 1) {
            shortCode.append("F");
        }

        StringBuilder result = new StringBuilder();
        for (int i = 0; i < shortCode.length(); i += 2) {
            result.append(shortCode.charAt(i + 1)).append(shortCode.charAt(i));
        }

        return result.toString();
    }
}
